﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ZF.BLL.Page;
using ZF.Model;
using System.Text;
using System.Collections.Specialized;
using Gateway;
using ZF.BLL;

namespace ZF.WS.shop
{

    /// <summary>
    /// 创建该页面文件时，请留心该页面文件中无任何HTML代码及空格。
    /// 该页面称作“通知页”，是异步被支付宝服务器所调用。
    /// 当支付宝的订单状态改变时，支付宝服务器则会自动调用此页面，因此请做好自身网站订单信息与支付宝上的订单的同步工作
    /// </summary>
    public partial class Alipay_Notify : PageBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            bool success = false;
             var postData = "";
            foreach (var key in Request.Form.AllKeys)
            {
                postData += Request.Form[key] + "\r\n";
            }
            if (CheckSign())
            {
                using (var ts = new System.Transactions.TransactionScope())
                {
                    using (var dc = SiteInfo.CreateDBDataContext())
                    {
                        var orderNo = string.Concat(Request.Form["out_trade_no"]);
                        string strPrice = Request.Form["total_fee"];//金额
                        var order = dc.SP_Order.FirstOrDefault(p => p.OrderNo == orderNo);
                        if (order != null)
                        {
                            if (strPrice == order.LastPrice.ToString() && (order.Status == (int)OrderStatus.下单10 || order.Status == (int)OrderStatus.确认20 || order.Status == (int)OrderStatus.处理中30) &&
                                     !order.IsPayed && (order.PayStatus == PayStatus.NEW_PAY.ToString() || order.PayStatus == PayStatus.WAIT_BUYER_PAY.ToString()))
                            {
                                bool flag = false;
                               
                                var alipayLog = new SP_AlipayLog()
                                {
                                    AddTime = DateTime.Now,
                                    PostData = postData,
                                    OrderId = order.OrderId,
                                    OrderNo = order.OrderNo,
                                    Price = order.LastPrice,
                                    TradeStatus = Request.Form["trade_status"],
                                };
                                if (Request.Form["trade_status"] == PayStatus.WAIT_BUYER_PAY.ToString())//   判断支付状态_等待买家付款（文档中有枚举表可以参考）            
                                {
                                    order.PayStatus = PayStatus.WAIT_BUYER_PAY.ToString();
                                    order.PSLastTime = DateTime.Now;
                                    flag = true;
                                }
                                else if (Request.Form["trade_status"] == PayStatus.TRADE_SUCCESS.ToString() || Request.Form["trade_status"] == PayStatus.TRADE_FINISHED.ToString())//   判断支付状态_交易成功结束（文档中有枚举表可以参考）   
                                {
                                    if (!(order.PayStatus == PayStatus.TRADE_FINISHED.ToString() || order.PayStatus == PayStatus.TRADE_SUCCESS.ToString()))
                                    {
                                        order.PayStatus = Request.Form["trade_status"];//支付状态
                                        order.PSLastTime = DateTime.Now;//最后支付状态变更时间
                                        order.IsPayed = true;//是否已支付
                                        order.Paid = order.LastPrice;//支付价格
                                        order.PayTime = DateTime.Now;//支付时间
                                        order.AlipayAccount = Request.Form["buyer_id"];
                                        order.SerialNumber = Request.Form["trade_no"];
                                    }
                                    flag = true;
                                }
                                else if (Request.Form["trade_status"] == "TRADE_CLOSED")
                                {
                                    //交易关闭
                                }
                                else
                                {
                                    //更新自己数据库的订单语句，请自己填写一下
                                }
                                dc.SP_AlipayLog.InsertOnSubmit(alipayLog);
                                try
                                {
                                    dc.SubmitChanges();
                                    ts.Complete();
                                    success = flag;
                                }
                                catch (Exception ex)
                                {
                                    SiteInfo.InsertLog(ex);
                                }
                            }
                        }
                    }
                }
                Response.Write(success ? "success" : "fail");
                Response.End();
            }
            else
            {
                SiteInfo.InsertLog("Alipay_Notify", postData);
                Response.Write("fail");
                Response.End();
            }

            #region
            //if (mysign == sign && responseTxt == "true")   //验证支付发过来的消息，签名是否正确，只要成功进如这个判断里，则表示该页面已被支付宝服务器成功调用
            ////但判断内出现自身编写的程序相关错误导致通知给支付宝并不是发送success的消息或没有更新客户自身的数据库的情况，请自身程序编写好应对措施，否则查明原因时困难之极
            //{
            //    if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")//   判断支付状态_等待买家付款（文档中有枚举表可以参考）            
            //    {
            //        //更新自己数据库的订单语句，请自己填写一下
            //        string strOrderNO = Request.Form["out_trade_no"];//订单号
            //        string strPrice = Request.Form["total_fee"];//金额    如果你申请了商家购物卷功能，在返回信息里面请不要做金额的判断，否则会校验通过不了。
            //    }
            //    else if (Request.Form["trade_status"] == "TRADE_FINISHED" || Request.Form["trade_status"] == "TRADE_SUCCESS")//   判断支付状态_交易成功结束（文档中有枚举表可以参考）   
            //    {
            //        //更新自己数据库的订单语句，请自己填写一下
            //        string strOrderNO = Request.Form["out_trade_no"];//订单号
            //        string strPrice = Request.Form["total_fee"];//金额   
            //    }
            //    else if (Request.Form["trade_status"] == "TRADE_CLOSED")
            //    {
            //        //交易关闭
            //    }
            //    else
            //    {

            //        //更新自己数据库的订单语句，请自己填写一下
            //    }
            //    Response.Write("fail");
            //    //Response.Write("success");     //返回给支付宝消息，成功，请不要改写这个success
            //    //success与fail及其他字符的区别在于，支付宝的服务器若遇到success时，则不再发送请求通知（即不再调用该页面，让该页面再次运行起来），
            //    //若不是success，则支付宝默认没有收到成功的信息，则会反复不停地调用该页面直到失效，有效调用时间是24小时以内。

            //    //最好写TXT文件，以记录下是否异步返回记录。

            //    ////写文本，纪录支付宝返回消息，比对md5计算结果（如网站不支持写txt文件，可改成写数据库）
            //    //string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;
            //    //StreamWriter fs = new StreamWriter(Server.MapPath("Notify_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);
            //    //fs.Write(TOEXCELLR);
            //    //fs.Close();
            //}
            //else
            //{
            //    Response.Write("fail");

            //    //最好写TXT文件，以记录下是否异步返回记录。

            //    //写文本，纪录支付宝返回消息，比对md5计算结果（如网站不支持写txt文件，可改成写数据库）
            //    string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;
            //    StreamWriter fs = new StreamWriter(Server.MapPath("Notify_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);
            //    fs.Write(TOEXCELLR);
            //    fs.Close();
            //}
            #endregion
        }

        private bool CheckSign()
        {
            var alipayset = SiteInfo.SystemConfig.AlipaySet;

            string alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify";
            //string alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?";//此路径是在上面链接地址无法起作用时替换使用。
            string partner = alipayset.Partner; 		//partner合作伙伴id（必须填写）
            string key = alipayset.Key; //partner 的对应交易安全校验码（必须填写）
            string _input_charset = "utf-8";//编码类型，完全根据客户自身的项目的编码格式而定，千万不要填错。否则极其容易造成MD5加密错误。

            alipayNotifyURL = alipayNotifyURL + "&partner=" + partner + "&notify_id=" + Request.Form["notify_id"];

            //获取支付宝ATN返回结果，true是正确的订单信息，false 是无效的
            string responseTxt = AliPay.Get_Http(alipayNotifyURL, 120000);

            string sign = Request.Form["sign"];


            //*******加密签名程序开始*******
            int i;
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestarr = coll.AllKeys;

            //进行排序；
            string[] Sortedstr = AliPay.BubbleSort(requestarr);


            //构造待md5摘要字符串 ；
            StringBuilder prestr = new StringBuilder();

            for (i = 0; i < Sortedstr.Length; i++)
            {
                if (Request.Form[Sortedstr[i]] != "" && Sortedstr[i] != "sign" && Sortedstr[i] != "sign_type")
                {
                    if (i == Sortedstr.Length - 1)
                    {
                        prestr.Append(Sortedstr[i] + "=" + Request.Form[Sortedstr[i]]);
                    }
                    else
                    {
                        prestr.Append(Sortedstr[i] + "=" + Request.Form[Sortedstr[i]] + "&");

                    }
                }
            }

            prestr.Append(key);

            string mysign = AliPay.GetMD5(prestr.ToString(), _input_charset);
            //*******加密签名程序结束*******
            return mysign == sign && responseTxt == "true";


        }







    }
}
